using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Diagnostics;
using System.ComponentModel;
using System.Reflection;
using System.Collections;
using System.Windows.Forms;
using System.Transactions;
using THSLib;
using THSERP.BusinessEntities;
namespace THSERP.BaseProvider
{
    public partial class ERPModuleEntities
    {
        #region Constant        
        public const String AAStatusColumn = "AAStatus";
        public const String AACreatedUser = "AACreatedUser";
        public const String AACreatedDate = "AACreatedDate";
        public const String AAUpdatedUser = "AAUpdatedUser";
        public const String AAUpdatedDate = "AAUpdatedDate";
        
        public const String cstNewObjectText = "***NEW***";
        public const String cstTemplateObjectText = "***TEMPLATE***";
        #endregion

        #region variables
        /// <summary>
        /// Variable define module which ModuleEntities belong to
        /// </summary>
        private BaseModuleERP _module;

        /// <summary>
        /// Variable define Current Object
        /// </summary>
        public BusinessObject MainObject;

        /// <summary>
        /// Variable define module objects
        /// </summary>
        public BusinessObjectCollection ModuleObjects;

        //hieu nguyen created Dec 30,2008
        public BusinessObject OrgMainObject;

        /// <summary>
        /// Variable define BindingSource of Current Object
        /// </summary>
        public BindingSource MainObjectBindingSource;

        /// <summary>
        /// Variable define BindingSource collection of module objects
        /// </summary>
        public BindingSourceCollection ModuleObjectsBindingSource;

        public bool IsValid = true;

        #endregion       

        #region Public Properties
        public BaseModuleERP Module
        {
            get
            {
                return _module;
            }
            set
            {
                _module = value;
            }
        }
        #endregion

        #region Constructor
        public ERPModuleEntities()
        {
            MainObjectBindingSource = new BindingSource();            
            ModuleObjects = new BusinessObjectCollection();            
            ModuleObjectsBindingSource = new BindingSourceCollection();            
        }

        public virtual void InitModuleEntity()
        {
            InitMainObject();
            InitModuleObjects();
            InitModuleObjectList();
            
            InitMainObjectBindingSource();
            InitModuleObjectsBindingSource();            
        }

        public virtual void InitGridControlInTHSList()
        {

        }
       
        #endregion

        #region Init MainObject, ModuleObjects Functions

        public virtual void InitMainObject()
        {

        }

        /// <summary type="Initialize">
        /// Initialize Module Objects
        /// </summary>
        public virtual void InitModuleObjects()
        {
            
        }

        public virtual void InitModuleObjectList()
        {

        }
       

        /// <summary type="Initialize">
        /// Initialize Current Object Binding Source
        /// </summary>
        public virtual void InitMainObjectBindingSource()
        {
            if(MainObject!=null)
                MainObjectBindingSource.DataSource = MainObject.GetType();                
        }

        /// <summary type="Initialize">
        /// Initialize Module Objects Binding Source
        /// </summary>
        public virtual void InitModuleObjectsBindingSource()
        {
            try
            {
                foreach (DictionaryEntry de in ModuleObjects)
                {
                    BindingSource bds = new BindingSource();
                    bds.DataSource = ModuleObjects[de.Key.ToString()].GetType();
                    ModuleObjectsBindingSource.Add(de.Key.ToString(), bds);
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(this.GetType().FullName + "-InitModuleObjectsBindingSource-" + e.Message);
            }
        }        

        #endregion

        #region Register Module Object Event
        /// <summary type="ObjectRule">
        /// Create Module Object Rule
        /// </summary>
        /// <functiontype>Create Object Rule</functiontype>
        public virtual void CreateMainObjectRule()
        {
                       
            String strMainObjectTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);

            DataSet dsColumns = THSDbUtil.GetNotAllowNullTableColumns(strMainObjectTableName);
            
            if (dsColumns.Tables.Count > 0)
            {
                foreach (DataRow rowColumn in dsColumns.Tables[0].Rows)
                {
                    String strColumnName = rowColumn["COLUMN_NAME"].ToString();
                    String strBrokenRuleDescription = String.Empty;
                    //Add rule if column is not primary key
                    if (!THSDbUtil.IsPrimaryKey(strMainObjectTableName, strColumnName))
                    {
                        //If column is foreign key and not allow null
                        if (THSDbUtil.IsForeignKey(strMainObjectTableName, strColumnName))
                        {                            
                            strBrokenRuleDescription = String.Format("{0} does not exist", strColumnName);
                            BusinessRule foreignKeyRule = new BusinessRule(
                                                                strColumnName, 
                                                                strBrokenRuleDescription, 
                                                                IsValidForeignKeyProperty);
                            MainObject.BusinessRuleCollections.Add(foreignKeyRule);
                            
                        }
                        //If column is non foreign key and not allow null
                        else
                        {                            
                            strBrokenRuleDescription = String.Format("Invalid {0}", strColumnName);
                            BusinessRule nonForeignKeyRule = new BusinessRule(
                                                                    strColumnName, 
                                                                    strBrokenRuleDescription, 
                                                                    IsValidNonForeignKeyPropety);
                            MainObject.BusinessRuleCollections.Add(nonForeignKeyRule);                            
                        }
                    }
                }
            }
            dsColumns.Dispose();
        }

        protected List<BusinessRule> BackupMainObjectBusinessRule()
        {
            List<BusinessRule> mainObjectRules = new List<BusinessRule>();
            foreach (BusinessRule rule in MainObject.BusinessRuleCollections)
            {
                mainObjectRules.Add(rule);
            }
            return mainObjectRules;
        }

        protected void RestoreMainObjectBusinessRule(List<BusinessRule> mainObjectRules)
        {
            foreach (BusinessRule rule in mainObjectRules)
            {
                MainObject.BusinessRuleCollections.Add(rule);
            }
        }


        private bool IsValidForeignKeyProperty(String strForeignKeyColumn)
        {
            try
            {
               
                //String strMainObjectTableName = MainObject.GetType().Name.Substring(0, MainObject.GetType().Name.Length - 4);
                String strMainObjectTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);
                String strPrimaryTable = THSDbUtil.GetPrimaryTableWhichForeignColumnReferenceTo(strMainObjectTableName, strForeignKeyColumn);
                String strPrimaryColumn = THSDbUtil.GetPrimaryColumnWhichForeignColumnReferenceTo(strMainObjectTableName, strForeignKeyColumn);
                BaseBusinessController objPrimaryTableObjectController = BusinessControllerFactory.GetBusinessController(strPrimaryTable + "Controller");
                int iForeignKeyColumnValue = Convert.ToInt32(THSDbUtil.GetPropertyValue(MainObject, strForeignKeyColumn));
                if (iForeignKeyColumnValue > 0)
                    return objPrimaryTableObjectController.IsExist(iForeignKeyColumnValue);
                else
                    return false;
            }
            catch (Exception)
            {
                return false;
            }

        }

        private bool IsValidNonForeignKeyPropety(String strNonForeignKeyColumn)
        {
            try
            {
               
                PropertyInfo property = MainObject.GetType().GetProperty(strNonForeignKeyColumn);
                if (property.PropertyType.Equals(typeof(int)))
                {
                    object objPropertyValue = THSDbUtil.GetPropertyValue(MainObject, strNonForeignKeyColumn);                    
                    int iConvert = Convert.ToInt32(objPropertyValue);
                    return true;
                }
                else if (property.PropertyType.Equals(typeof(double)))
                {
                    object objPropertyValue = THSDbUtil.GetPropertyValue(MainObject, strNonForeignKeyColumn);                    
                    double dbConvert = Convert.ToDouble(objPropertyValue);
                    return true;
                }
                else if (property.PropertyType.Equals(typeof(decimal)))
                {
                    object objPropertyValue = THSDbUtil.GetPropertyValue(MainObject, strNonForeignKeyColumn);                    
                    decimal dcConvert = Convert.ToDecimal(objPropertyValue);
                    return true;
                }
                else if (property.PropertyType.Equals(typeof(short)))
                {
                    object objPropertyValue = THSDbUtil.GetPropertyValue(MainObject, strNonForeignKeyColumn);                    
                    short sConvert = Convert.ToInt16(objPropertyValue);
                    return true;
                }
                else if (property.PropertyType.Equals(typeof(bool)))
                {
                    object objPropertyValue = THSDbUtil.GetPropertyValue(MainObject, strNonForeignKeyColumn);                    
                    bool bConvert = Convert.ToBoolean(objPropertyValue);
                    return true;
                }
                else if (property.PropertyType.Equals(typeof(DateTime)))
                {
                    object objPropertyValue = THSDbUtil.GetPropertyValue(MainObject, strNonForeignKeyColumn);                    
                    DateTime dtConvert = Convert.ToDateTime(objPropertyValue);
                    return true;
                }
                else if (property.PropertyType.Equals(typeof(string)) || property.PropertyType.Equals(typeof(String)))
                {
                    object objPropertyValue = THSDbUtil.GetPropertyValue(MainObject, strNonForeignKeyColumn);                    
                    String strConvert = Convert.ToString(objPropertyValue);
                    if (!String.IsNullOrEmpty(strConvert))
                        return true;
                    else
                        return false;
                }

                return false;
            }
            catch (Exception)
            {
                return false;
            }

        }

        /// <summary type="ObjectEvent">
        /// Subcribe Main Object Event
        /// </summary>        
        public void SubcribeMainObjectEvent()
        {
           // MainObject.OnValid += (BusinessObject.EventHandler)ModuleObject_OnValid;
           // MainObject.OnInvalid += (BusinessObject.EventHandler)ModuleObject_OnInvalid;
           // MainObject.PropertyChanged += new PropertyChangedEventHandler(MainObject_PropertyChanged);
           // MainObject.OnChanged += (BusinessObject.EventHandler)ModuleObject_OnChanged;
              MainObject.PropertyChanged += new PropertyChangedEventHandler(MainObject_OnChanged);
        }
        /// <summary>
        /// Subcribe Module object Event
        /// </summary>
        /// <remarks>HieuNH_12/05/2010</remarks>
        /// 
        public void SubcribeModueObjectEvent(String strModuleObjectName)
        {
            ModuleObjects[strModuleObjectName].PropertyChanged += new PropertyChangedEventHandler(ModuleObject_OnChanged);
        }

        /// <summary type="ObjectEvent">
        /// Delegate Function for Event Valid of Module Object
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>        
        private void ModuleObject_OnValid(object sender, EventArgs e)
        {
            if (!Module.Toolbar.IsNullOrNoneAction())
            {
                DevExpress.XtraBars.BarButtonItem barbtnSave = Module.ParentScreen.GetToolbarButton(
                                                                            BaseToolbar.ToolbarAction, 
                                                                            BaseToolbar.ToolbarButtonSave);
                DevExpress.XtraBars.BarButtonItem barbtnDelete = Module.ParentScreen.GetToolbarButton(
                                                                                BaseToolbar.ToolbarAction, 
                                                                                BaseToolbar.ToolbarButtonDelete);
                if (barbtnSave != null)
                    barbtnSave.Enabled = true;
                if (barbtnDelete != null)
                {
                    if (Module.Toolbar.ModusAction == BaseToolbar.ModusEdit)
                        barbtnDelete.Enabled = true;
                }
                IsValid = true;
            }
        }

        /// <summary type="ObjectEvent">
        /// Delegate Function for Event Invalid of Module Object
        /// </summary>        
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ModuleObject_OnInvalid(object sender, EventArgs e)
        {
            if (!Module.Toolbar.IsNullOrNoneAction())
            {
                DevExpress.XtraBars.BarButtonItem barbtnSave = Module.ParentScreen.GetToolbarButton(
                                                                                BaseToolbar.ToolbarAction, 
                                                                                BaseToolbar.ToolbarButtonSave);
                DevExpress.XtraBars.BarButtonItem barbtnDelete = Module.ParentScreen.GetToolbarButton(
                                                                                BaseToolbar.ToolbarAction, 
                                                                                BaseToolbar.ToolbarButtonDelete);
                if (barbtnSave != null)
                    barbtnSave.Enabled = false;
                if (barbtnDelete != null)
                    barbtnDelete.Enabled = false;
                IsValid = false;
            }
        }


        /// <summary type="ObjectEvent">
        /// Delegate Function for Event Invalid of Main Object
        /// </summary>        
        /// <remarks>HieuNH_12/05/2010</remarks>
        /// 
        public void MainObject_OnChanged(object sender, PropertyChangedEventArgs e)
        {
            if (((BusinessObject)sender).AllowPropertyChangedEvent && Module.Toolbar.IsNullOrNoneAction())
            {
               
                if (THSDbUtil.ColumnIsExist(THSUtil.GetTableNameFromBusinessObject((BusinessObject)sender), e.PropertyName))
                    Module.ActionEdit();
            }
        }

        /// <summary type="ObjectEvent">
        /// Delegate Function for Event Invalid of Module Object
        /// </summary>        
        /// <remarks>HieuNH_12/05/2010</remarks>
        /// 
        public void ModuleObject_OnChanged(object sender, PropertyChangedEventArgs e)
        {
            if (((BusinessObject)sender).AllowPropertyChangedEvent && Module.Toolbar.IsNullOrNoneAction())
            {
               
                if (THSDbUtil.ColumnIsExist(THSUtil.GetTableNameFromBusinessObject((BusinessObject)sender), e.PropertyName))
                    Module.ActionEdit();
            }
        }

        /// <summary>
        /// Lock property change event, prevent it from raising continuously in action chain
        /// </summary
        ///

        public void SetPropertyChangeEventLock(bool allow)
        {
            MainObject.AllowPropertyChangedEvent = allow;
            foreach (BusinessObject moduleObject in ModuleObjects.Values)
                moduleObject.AllowPropertyChangedEvent = allow;
        }

        //protected virtual void MainObject_PropertyChanged(object sender, PropertyChangedEventArgs e)
        //{
        //    if (Module.Toolbar.IsNullOrNoneAction())
        //    {
        //        if ((sender as BusinessObject).AllowPropertyChangedEvent)
        //        {
        //            Module.Toolbar.ModusAction = BaseToolbar.ModusEdit;

        //            //DialogResult dlgresult = MessageQuestion.ShowEditMessageQuestion();
        //            //if (dlgresult == DialogResult.Yes)
        //            //{
        //            //    Module.ActionEdit();
        //            //}
        //            //else
        //            //{
        //            //    Module.ActionInvalidate();
        //            //}

        //            //String strMainTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);
        //            //STFieldsInfo objSTFieldsInfo = new STFieldsController().GetFirstFieldByModuleIDAndUserGroupIDAndFieldDataSourceAndFieldDataMember(
        //            //                                                        Module.ModuleID, THSApp.CurrentUserGroupInfo.ADUserGroupID,
        //            //                                                        strMainTableName, e.PropertyName);
        //            //if (objSTFieldsInfo != null)
        //            //{
        //            //    RefreshControl(e.PropertyName, objSTFieldsInfo);
        //            //}
        //        }                   
        //    }
        //}

        private void RefreshControl(String strPropertyName,STFieldsInfo objSTFieldsInfo)
        {            
            String strMainTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);
            object objPropertyValue = THSDbUtil.GetPropertyValue(MainObject, strPropertyName);
            String strControlType = objSTFieldsInfo.STFieldType;
            Control ctrl = Module.Controls[objSTFieldsInfo.STFieldName];
            if (strControlType.Equals("THSTextBox"))
                ctrl.Text = objPropertyValue.ToString();
            else if (strControlType.Equals("THSComboBox"))
                (ctrl as DevExpress.XtraEditors.ComboBoxEdit).EditValue = objPropertyValue;
            else if (strControlType.Equals("THSLookupEdit"))
                (ctrl as DevExpress.XtraEditors.LookUpEdit).EditValue = objPropertyValue;
            else if (strControlType.Equals("THSDateEdit"))
                (ctrl as DevExpress.XtraEditors.DateEdit).DateTime = Convert.ToDateTime(objPropertyValue);
            else if (strControlType.Equals("THSTimeEdit"))
                (ctrl as DevExpress.XtraEditors.TimeEdit).Time = Convert.ToDateTime(objPropertyValue);
            else if (strControlType.Equals("THSCheckEdit"))
                (ctrl as DevExpress.XtraEditors.CheckEdit).EditValue = objPropertyValue;

            ctrl.Refresh();
        }

        
        #endregion

        #region Invalidate functions

        public virtual void Invalidate(int iObjectID)
        {
            InvalidateMainObject(iObjectID);
            InvalidateModuleObjects(iObjectID);
        }

        /// <summary type="Invalidate">
        /// Invalidate Current Object
        /// </summary>
        /// <param name="iObjectID"></param>
        public virtual void InvalidateMainObject(int iObjectID)
        {
            //hieu.nguyen
            //if (iObjectID > 0)
            //{
            List<BusinessRule> mainObjectRules = BackupMainObjectBusinessRule();
            
            Type typMainObjectType = MainObject.GetType();
            BaseBusinessController objMainObjectController = new BaseBusinessController(typMainObjectType);            
            MainObject = (BusinessObject)objMainObjectController.GetObjectByID(iObjectID);

            if (MainObject == null)
                return;
            OrgMainObject = (BusinessObject)MainObject.Clone();
            RestoreMainObjectBusinessRule(mainObjectRules);
            SubcribeMainObjectEvent();

            UpdateMainObjectBindingSource();
        //}
    }
        
        public virtual void InvalidateModuleObject(BusinessObject obj)
        {
            String strModuleObjectName = THSUtil.GetTableNameFromBusinessObject(obj);
            if (ModuleObjects[strModuleObjectName] != null)
            {
                ModuleObjects[strModuleObjectName] = obj;
                //call envent module object propertychanged_HieuNH/12/05/2010
                SubcribeModueObjectEvent(strModuleObjectName);
                UpdateModuleObjectBindingSource(strModuleObjectName);
            }
        }

        
        public virtual void InvalidateModuleObject(ERPModuleItemsEntity entItem, String strModuleObjectName)
        {
            BusinessObject obj = entItem.SetToBusinessObject(strModuleObjectName);
            InvalidateModuleObject(obj);
        }
        /// <summary type="Invalidate">
        /// Invalidate Module Objects
        /// </summary>
        public virtual void InvalidateModuleObjects(int iObjectID)
        {
            
        }

        public virtual void InvalidateModuleItemObjectFromModuleItemsEntityList(int iPos)
        {

        }        
        
        #endregion

        #region Set Default Main Object, Module Objects functions        

        public virtual void SetDefaultMainObject()
        {
            try
            {
               
                List<BusinessRule> mainObjectRules = BackupMainObjectBusinessRule();

                

                //If not Exist Template object,create new template object
                if (!IsExistTemplateObject())
                {
                    //Renew Current Object
                    String strMainObjectName = MainObject.GetType().Name;
                    MainObject = BusinessObjectFactory.GetBusinessObject(strMainObjectName);

                    //Get Table which Main Object Represent
                    String strMainObjectTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);

                    String strPrimaryColumn = strMainObjectTableName.Substring(0, strMainObjectTableName.Length - 1) + "ID";

                    THSDbUtil.SetPropertyValue(MainObject, strPrimaryColumn.Substring(0, strPrimaryColumn.Length - 2) + "No", cstNewObjectText);


                    //Set Default Value for all property is foreign column and not allow null
                    DataSet dsForeignKeys = THSDbUtil.GetTableForeignKeys(strMainObjectTableName);
                    if (dsForeignKeys.Tables.Count > 0)
                    {
                        foreach (DataRow rowForeignKey in dsForeignKeys.Tables[0].Rows)
                        {
                            String strForeignKeyPropertyName = rowForeignKey["COLUMN_NAME"].ToString();
                            if (!THSDbUtil.ColumnIsAllowNull(strMainObjectTableName, strForeignKeyPropertyName))
                            {
                                String strPrimaryTable = THSDbUtil.GetPrimaryTableWhichForeignColumnReferenceTo(
                                                                    strMainObjectTableName,
                                                                    strForeignKeyPropertyName);
                                Type typPrimaryTableObjectType = BusinessObjectFactory.GetBusinessObjectType(strPrimaryTable + "Info");
                                //BaseBusinessController objPrimaryTableController = new BaseBusinessController(BusinessObjectFactory.GetBusinessObjectType(strPrimaryTable + "Info"));
                                BaseBusinessController objPrimaryTableController = new BaseBusinessController(typPrimaryTableObjectType);

                                int iPrimaryTableObjectID = objPrimaryTableController.GetFirstObjectID();
                                
                            }
                        }
                    }
                }
                //if exist template object,copy template object to main object
                else
                {
                    //Get Table which Main Object Represent
                    String strMainObjectTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);

                    String strPrimaryColumn = strMainObjectTableName.Substring(0, strMainObjectTableName.Length - 1) + "ID";

                    BaseBusinessController objMainObjectController = BusinessControllerFactory.GetBusinessController(strMainObjectTableName + "Controller");
                    BusinessObject objTemplateObject = (BusinessObject)objMainObjectController.GetTemplateObject();
                    MainObject = (BusinessObject)objTemplateObject.Clone();
                    THSDbUtil.SetPropertyValue(MainObject, strPrimaryColumn.Substring(0, strPrimaryColumn.Length - 2) + "No", cstNewObjectText);
                    THSDbUtil.SetPropertyValue(MainObject, AAStatusColumn, BusinessObject.DefaultAAStatus);
                }

                RestoreMainObjectBusinessRule(mainObjectRules);
                UpdateMainObjectBindingSource();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }

        /// <summary type="Set">
        /// Set Default Module Objects
        /// </summary>
        public virtual void SetDefaultModuleObjects()
        {
            String[] keysArray = new String[ModuleObjects.Count];
            ModuleObjects.Keys.CopyTo(keysArray, 0);
            for (int i = 0; i < keysArray.Length; i++)
            {
                String strModuleObjectName = keysArray[i].ToString();
                SetDefaultModuleObject(strModuleObjectName);
            }
        }

        public virtual void SetDefaultModuleObject(String strModuleObjectName)
        {
           

            //Renew BusinessObject
            String strModuleObjectTypeName = ModuleObjects[strModuleObjectName].GetType().Name;
            ModuleObjects[strModuleObjectName] = BusinessObjectFactory.GetBusinessObject(strModuleObjectTypeName);

            //Get Table which Business object Represent
            //String strObjectTableName = ModuleObjects[strModuleObjectName].GetType().Name.Substring(0, ModuleObjects[strModuleObjectName].GetType().Name.Length - 4);
            String strObjectTableName = THSUtil.GetTableNameFromBusinessObject(ModuleObjects[strModuleObjectName]);

            //Set Default Value for all property is foreign column and not allow null
            DataSet dsForeignKeys = THSDbUtil.GetTableForeignKeys(strObjectTableName);
            if (dsForeignKeys.Tables.Count > 0)
            {
                foreach (DataRow rowForeignKey in dsForeignKeys.Tables[0].Rows)
                {
                    String strForeignKeyPropertyName = rowForeignKey["COLUMN_NAME"].ToString();
                    if (!THSDbUtil.ColumnIsAllowNull(strObjectTableName, strForeignKeyPropertyName))
                    {
                        String strPrimaryTable = THSDbUtil.GetPrimaryTableWhichForeignColumnReferenceTo(
                                                            strObjectTableName,
                                                            strForeignKeyPropertyName);

                        String strMainObjectTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);                        
                        if (!strPrimaryTable.Equals(strMainObjectTableName))
                        {
                            BaseBusinessController objPrimaryTableController = new BaseBusinessController(BusinessObjectFactory.GetBusinessObjectType(strPrimaryTable + "Info"));
                            //hieu.nguyen remove.26/072011. No need to set default product to module object
                            //int iPrimaryTableObjectID = objPrimaryTableController.GetFirstObjectID();
                            //THSDbUtil.SetPropertyValue(
                            //            ModuleObjects[strModuleObjectName],
                            //            strForeignKeyPropertyName,
                            //            iPrimaryTableObjectID);
                        }
                    }
                }
            }
            UpdateModuleObjectBindingSource(strModuleObjectName);

        }

        public virtual void SetDefaultModuleObjectsList()
        {
            
        }

        public virtual void DuplicateModuleObjectList()
        {

        }
        #endregion

        #region Update Main Object, Module Objects Binding Source Functions
        /// <summary type="Update">
        /// Update Binding Source of Main Object
        /// </summary>        
        public virtual void UpdateMainObjectBindingSource()
        {           
            MainObjectBindingSource.DataSource = this.MainObject;
            MainObjectBindingSource.ResetBindings(false);
            
        }

        /// <summary type="Update">
        /// Update Binding Source of Module Objects
        /// </summary>        
        public virtual void UpdateModuleObjectsBindingSource()
        {
            foreach (DictionaryEntry de in ModuleObjects)
            {
                ModuleObjectsBindingSource[de.Key.ToString()].DataSource = de.Value;
            }
        }

        /// <summary type="Update">
        /// Update Binding Source Of Module Object By Module Object Name
        /// </summary>
        /// <param name="strModuleObjectName">Module Object Name will be updated</param>
        public virtual void UpdateModuleObjectBindingSource(String strModuleObjectName)
        {
            ModuleObjectsBindingSource[strModuleObjectName].DataSource = ModuleObjects[strModuleObjectName];
            //ModuleObjectsBindingSource[strModuleObjectName].ResetBindings(false);
        }
        #endregion

        #region Function for create Module Entity  
      
        public virtual String GetMainObjectNo()
        {
            String strMainObjectNo = String.Empty;
            GENumberingController objGENumberingController = new GENumberingController();
            GENumberingInfo objGENumberingInfo = (GENumberingInfo)new GENumberingController().GetObjectByName(Module.Name);
            if (objGENumberingInfo != null)
            {
                strMainObjectNo = String.Format("{0}{1}", objGENumberingInfo.GENumberingPrefix, objGENumberingInfo.GENumberingStart);
            }            
            return strMainObjectNo;
        }
        
        public virtual int CreateMainObject()
        {
           
            int iObjectID = 0;
            bool bIsEditObjectNo = true;

            //Get Table which Business object Represent            
            String strMainObjectTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);
            BaseBusinessController objMainObjectController = BusinessControllerFactory.GetBusinessController(strMainObjectTableName + "Controller");
            
            
            String strPrimaryColumn = strMainObjectTableName.Substring(0, strMainObjectTableName.Length - 1) + "ID";
            String strColumnNo = strMainObjectTableName.Substring(0, strMainObjectTableName.Length - 1) + "No";
            String strMainObjectNo = THSDbUtil.GetPropertyValue(MainObject, strColumnNo).ToString();
            if (strMainObjectNo.Equals(cstNewObjectText))
            {
                bIsEditObjectNo = false;
                //GENumberingController objGENumberingController = new GENumberingController();
                //GENumberingInfo objGENumberingInfo = (GENumberingInfo)new GENumberingController().GetObjectByName(Module.Name);
                //if (objGENumberingInfo != null)
                //{
                //    strMainObjectNo = String.Format("{0}{1}", objGENumberingInfo.GENumberingPrefix, objGENumberingInfo.GENumberingStart);
                //    THSDbUtil.SetPropertyValue(MainObject, strColumnNo, strMainObjectNo);
                //}

                
                strMainObjectNo = GetMainObjectNo();
                THSDbUtil.SetPropertyValue(MainObject, strColumnNo, strMainObjectNo);
            }

            //Set Created User, Created Date
            THSDbUtil.SetPropertyValue(MainObject, AACreatedUser, THSApp.CurrentUser);
            THSDbUtil.SetPropertyValue(MainObject, AACreatedDate, DateTime.Now);
            

            iObjectID = objMainObjectController.CreateObject(MainObject);

            if (iObjectID > 0)
            {
                if(!bIsEditObjectNo)
                    UpdateObjectNumbering();

                String strMainObjectPrimaryColumnName = THSDbUtil.GetTablePrimaryColumn(strMainObjectTableName);
                THSDbUtil.SetPropertyValue(MainObject, strMainObjectPrimaryColumnName, iObjectID);
            }

            return iObjectID;
        }
        
        /// <summary type="Save">
        /// Update Current Object
        /// </summary>
        /// <returns></returns>
        public virtual int UpdateMainObject()
        {
            int iObjectID = 0;
            String strMainObjectTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);
            BaseBusinessController objMainObjectController = BusinessControllerFactory.GetBusinessController(strMainObjectTableName + "Controller");

            //Set AAUpdatedUser, AAUpdatedDate
           
            THSDbUtil.SetPropertyValue(MainObject, AAUpdatedUser, THSApp.CurrentUser);
            THSDbUtil.SetPropertyValue(MainObject, AAUpdatedDate, DateTime.Now);

            iObjectID = objMainObjectController.UpdateObject(MainObject);
            
            return iObjectID;
        }

        /// <summary type="Save">
        /// Save Main Object
        /// </summary>
        /// <returns></returns>
        public virtual int SaveMainObject()
        {
            if (Module.Toolbar.IsNewAction())
                return CreateMainObject();
            else
                return UpdateMainObject();
        }

        public virtual bool IsExistTemplateObject()
        {
            String strMainObjectTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);
            BaseBusinessController objMainObjectController = BusinessControllerFactory.GetBusinessController(strMainObjectTableName + "Controller");
            BusinessObject objTemplateObject = (BusinessObject)objMainObjectController.GetTemplateObject();
            if (objTemplateObject != null)
                return true;
            return false;
        }


        public virtual void SaveModuleObjects()
        {

        }       
        
        public void UpdateObjectNumbering()
        {
            GENumberingController objGENumberingController = new GENumberingController();
            GENumberingInfo objGENumberingInfo = (GENumberingInfo)objGENumberingController.GetObjectByName(Module.Name);
            if (objGENumberingInfo != null)
            {
                               
                objGENumberingInfo.GENumberingStart++;
                objGENumberingController.UpdateObject(objGENumberingInfo);
            }
        }       
        #endregion

        #region Function for action New,Save,Delete Module Entity
        public virtual void New()
        {
            SetDefaultMainObject();
            SetDefaultModuleObjects();
            SetDefaultModuleObjectsList();
        }

        public virtual void Save()
        {

        }

        public virtual void Delete(int iObjectID)
        {
            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew))
            {
                try
                {
                    BaseBusinessController objCurrentObjectController = BusinessControllerFactory.GetBusinessController(MainObject.GetType().Name.Substring(0, MainObject.GetType().Name.Length - 4) + "Controller");
                    objCurrentObjectController.DeleteObject(iObjectID);
                    String strTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);
                    DeleteObjectRelations(strTableName, iObjectID);
                    scope.Complete();
                }
                catch (Exception ex)
                {
                    scope.Dispose();
                }
            }
        }

        /// <summary>
        /// Delete all relations of deleted object
        /// </summary>
        ///
        public virtual void DeleteObjectRelations(String strTableName, int iObjectID)
        {

        }

        public virtual void DeleteModuleObject(String strModuleObjectName, int iObjectID)
        {

        }

        public virtual void SaveMainObjectRelations()
        {

        }

        public virtual void SaveObjectItemRelations(ERPModuleItemsEntity entItems)
        {

        }

        /// <summary>
        /// Do something here after removing item object
        /// </summary>
        ///

        public virtual void DoActionAfterRemovingItemObject(String strItemTableName)
        {

        }

        /// <summary>
        /// Complete transaction and update inventory
        /// </summary>
        /// 
        public virtual bool CompleteTransaction()
        {
            return true;
        }
        #endregion

        #region Utitlity functions
        //public List<FATransactionsInfo> CopyFATransactionsList(List<FATransactionsInfo> lstSourceFATransactions)
        //{
        //    List<FATransactionsInfo> lstDestFATransaction = new List<FATransactionsInfo>();
        //    foreach (FATransactionsInfo objFATransactionsInfo in lstSourceFATransactions)
        //    {
        //        FATransactionsInfo objCopyTransactionsInfo = (FATransactionsInfo)objFATransactionsInfo.Clone();
        //        lstDestFATransaction.Add(objCopyTransactionsInfo);
        //    }

        //    return lstDestFATransaction;
        //}

        public List<ERPModuleItemsEntity> GetModuleItemsEntityList(String strModuleItemsEntityName)
        {
            List<ERPModuleItemsEntity> lstERPModuleItemsEntity = new List<ERPModuleItemsEntity>();
            foreach (FieldInfo field in this.GetType().GetFields())
            {
                if (field.FieldType.FullName.Contains("System.Collections.Generic"))
                {                    
                    Type[] arrType = field.FieldType.GetGenericArguments();
                    if (arrType[0].Name.Contains(strModuleItemsEntityName))
                    {
                        try
                        {
                            if (arrType[0].BaseType == typeof(ERPModuleItemsEntity))
                            {
                                lstERPModuleItemsEntity = (List<ERPModuleItemsEntity>)field.GetValue(this);
                                return lstERPModuleItemsEntity;
                            }
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message);
                            return null;
                        }
                    }
                }
            }
            return null;
        }

        public List<BusinessObject> GetBusinessObjectList(String strBusinessObjectName)
        {
            List<BusinessObject> lstBusinessObject = new List<BusinessObject>();
            foreach (FieldInfo field in this.GetType().GetFields())
            {
                if (field.FieldType.FullName.Contains("System.Collections.Generic"))
                {
                    Type[] arrType = field.FieldType.GetGenericArguments();
                    try
                    {
                        if (arrType[0].BaseType == typeof(BusinessObject))
                        {
                            lstBusinessObject = (List<BusinessObject>)field.GetValue(this);
                            return lstBusinessObject;
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                        return null;
                    }
                }
            }
            return null;
        }

        public virtual void UpdateInventory(ERPModuleItemsEntity entItems, String strUpdateStatus)
        {

        }
        
        #endregion        
        
        #region Generate Entity from Related Entity functions
        public virtual void GenerateEntity(BusinessObject objRelatedMainObjectInfo)
        {
            String strMainTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);
            String strModuleItemsTableName = strMainTableName.Substring(0, strMainTableName.Length - 1) + "Items";

            GenerateMainObject(objRelatedMainObjectInfo);

            GenerateModuleItemsList(objRelatedMainObjectInfo);
        }

        public virtual void GenerateMainObject(BusinessObject objRelatedMainObjectInfo)
        {
           
            String strMainTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);
            String strRelatedTableName = THSUtil.GetTableNameFromBusinessObject(objRelatedMainObjectInfo);
            String strPrefixMainTable = strMainTableName.Substring(0, 2);
            String strPrefixRelatedMainTable = strRelatedTableName.Substring(0, 2);

            String strMainObjectNoPropertyName = strMainTableName.Substring(0, strMainTableName.Length - 1) + "No";
            String strMainObjectStatusPropertyName = strMainTableName.Substring(0, strMainTableName.Length - 1) + "Status";
            String strMainObjectTypePropertyName = strMainTableName.Substring(0, strMainTableName.Length - 1) + "TypeCombo";

            PropertyInfo[] properties = MainObject.GetType().GetProperties();
            foreach (PropertyInfo prop in properties)
            {
                if (!THSDbUtil.IsPrimaryKey(strMainTableName, prop.Name))
                {
                    if (!THSDbUtil.IsForeignKey(strMainTableName, prop.Name))
                    {
                        if (!prop.Name.Equals(strMainObjectNoPropertyName) && !prop.Name.Equals(strMainObjectStatusPropertyName) && !prop.Name.StartsWith("AA") && !prop.Name.Equals(strMainObjectTypePropertyName))
                        {
                            if (prop.Name.StartsWith(strMainTableName.Substring(0, strMainTableName.Length - 1)))
                            {
                                String strRelatedPropertyName = strRelatedTableName.Substring(0, strRelatedTableName.Length - 1) + prop.Name.Substring(strMainTableName.Length-1);
                                PropertyInfo relatedProp = objRelatedMainObjectInfo.GetType().GetProperty(strRelatedPropertyName);
                                if (relatedProp != null)
                                {
                                    object objValue = relatedProp.GetValue(objRelatedMainObjectInfo, null);
                                    prop.SetValue(MainObject, objValue, null);
                                }
                            }
                            else
                            {
                                PropertyInfo relatedProperty = objRelatedMainObjectInfo.GetType().GetProperty(prop.Name);
                                if (relatedProperty != null)
                                {
                                    object objValue = relatedProperty.GetValue(objRelatedMainObjectInfo, null);
                                    prop.SetValue(MainObject, objValue, null);
                                }
                            }

                        }
                    }
                    else
                    {
                        PropertyInfo relatedProperty = objRelatedMainObjectInfo.GetType().GetProperty(prop.Name);
                        if (relatedProperty != null)
                        {
                            object objValue = relatedProperty.GetValue(objRelatedMainObjectInfo, null);
                            prop.SetValue(MainObject, objValue, null);
                        }
                    }
                }

            }

            UpdateMainObjectBindingSource();
        }

        public virtual void GenerateModuleItemsList(BusinessObject objRelatedMainObjectInfo)
        {

        }

        public ERPModuleItemsEntity GenerateERPModuleItemsEntity(BusinessObject objRelatedModuleItemsInfo, double dbRemainQty)
        {
           
            String strMainTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);
            String strRelatedModuleItemsTableName = THSUtil.GetTableNameFromBusinessObject(objRelatedModuleItemsInfo);
            String strMainTablePrimaryKey = THSDbUtil.GetTablePrimaryColumn(strMainTableName);
            String strModuleItemsTableName = strMainTableName.Substring(0, strMainTableName.Length - 1) + "Items";
            String strModuleItemProductQtyOldPropertyName = strModuleItemsTableName.Substring(0, strModuleItemsTableName.Length - 1) + "ProductQtyOld";
            String strModuleItemProductQtyPropertyName = strModuleItemsTableName.Substring(0, strModuleItemsTableName.Length - 1) + "ProductQty";
            String strRelatedModuleItemProductQtyPropertyName = strRelatedModuleItemsTableName.Substring(0, strRelatedModuleItemsTableName.Length - 1) + "ProductQty";

            ERPModuleItemsEntity entModuleItems = ERPModuleItemsEntityFactory.GetModuleItemsEntity(this.Module.Name);
            BusinessObject objModuleItemsInfo = BusinessObjectFactory.GetBusinessObject(strModuleItemsTableName + "Info");

            THSUtil.CopyObjectItems(objModuleItemsInfo, objRelatedModuleItemsInfo, strMainTableName);

            //PropertyInfo[] properties = objModuleItemsInfo.GetType().GetProperties();
            //foreach (PropertyInfo prop in properties)
            //{
            //    if (!THSDbUtil.IsPrimaryKey(strModuleItemsTableName, prop.Name))
            //    {
            //        if (!THSDbUtil.IsForeignKey(strModuleItemsTableName, prop.Name))
            //        {
            //            if (prop.Name.StartsWith(strModuleItemsTableName.Substring(0, strModuleItemsTableName.Length - 1)))
            //            {
            //                String strRelatedModuleItemPropertyName = strRelatedModuleItemsTableName.Substring(0, strRelatedModuleItemsTableName.Length - 1) + prop.Name.Substring(strModuleItemsTableName.Length - 1);
            //                PropertyInfo relatedModuleItemProperty = objRelatedModuleItemsInfo.GetType().GetProperty(strRelatedModuleItemPropertyName);
            //                if (relatedModuleItemProperty != null)
            //                {
            //                    object objValue = relatedModuleItemProperty.GetValue(objRelatedModuleItemsInfo, null);
            //                    prop.SetValue(objModuleItemsInfo, objValue, null);
            //                }
            //            }
            //        }
            //        else
            //        {
            //            if (!prop.Name.Equals(strMainTablePrimaryKey))
            //            {
            //                PropertyInfo relatedModuleItemProperty = objRelatedModuleItemsInfo.GetType().GetProperty(prop.Name);
            //                if (relatedModuleItemProperty != null)
            //                {
            //                    object objValue = relatedModuleItemProperty.GetValue(objRelatedModuleItemsInfo, null);
            //                    prop.SetValue(objModuleItemsInfo, objValue, null);
            //                }
            //            }
            //        }
            //    }
            //}

            //Set Quantity Ship
            THSDbUtil.SetPropertyValue(
                    objModuleItemsInfo,
                    strModuleItemProductQtyOldPropertyName,
                    0);
            THSDbUtil.SetPropertyValue(
                    objModuleItemsInfo,
                    strModuleItemProductQtyPropertyName,
                    Convert.ToDouble(THSDbUtil.GetPropertyValue(objRelatedModuleItemsInfo, strRelatedModuleItemProductQtyPropertyName)) - dbRemainQty);

            entModuleItems.GetFromBusinessObject(objModuleItemsInfo);


            AddItemsRelations(entModuleItems, objRelatedModuleItemsInfo);

            return entModuleItems;
        }

        public virtual void AddItemsRelations(ERPModuleItemsEntity entModuleItems, BusinessObject objRelatedModuleItemsInfo)
        {

        }




#if never                   

        
        public virtual void GenerateEntityFromRelatedEntity(BusinessObject objRelatedModuleMainObjectInfo)
        {
            String strMainTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);
            String strModuleItemsTableName = strMainTableName.Substring(0, strMainTableName.Length - 1) + "Items";

            GenerateMainObjectFromRelatedBusinessObject(objRelatedModuleMainObjectInfo);

            GenerateModuleItemsFromRelatedModuleMainObjectsInfo(objRelatedModuleMainObjectInfo);
            
        }

        public virtual void GenerateMainObjectFromRelatedBusinessObject(BusinessObject objBusinessObject)
        {
           
            String strMainTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);
            String strRelatedTableName = THSUtil.GetTableNameFromBusinessObject(objBusinessObject);

            String strMainObjectStatusPropertyName = strMainTableName.Substring(0, strMainTableName.Length - 1) + "Status";
            String strMainObjectTypePropertyName = strMainTableName.Substring(0, strMainTableName.Length - 1) + "TypeCombo";

            PropertyInfo[] properties = MainObject.GetType().GetProperties();
            foreach (PropertyInfo prop in properties)
            {
                if (!THSDbUtil.IsPrimaryKey(strMainTableName, prop.Name))
                {
                    if (!THSDbUtil.IsForeignKey(strMainTableName, prop.Name))
                    {
                        if (!prop.Name.Equals(strMainObjectStatusPropertyName) && !prop.Name.StartsWith("AA") && !prop.Name.Equals(strMainObjectTypePropertyName))
                        {
                            if (prop.Name.StartsWith(strMainTableName.Substring(0, strMainTableName.Length - 1)))
                            {
                                String strRelatedPropertyName = strRelatedTableName.Substring(0, strRelatedTableName.Length - 1) + prop.Name.Substring(10);
                                PropertyInfo relatedProp = objBusinessObject.GetType().GetProperty(strRelatedPropertyName);
                                if (relatedProp != null)
                                {
                                    object objValue = relatedProp.GetValue(objBusinessObject, null);
                                    prop.SetValue(MainObject, objValue, null);
                                }
                            }
                            else
                            {
                                PropertyInfo relatedProperty = objBusinessObject.GetType().GetProperty(prop.Name);
                                if (relatedProperty != null)
                                {
                                    object objValue = relatedProperty.GetValue(objBusinessObject, null);
                                    prop.SetValue(MainObject, objValue, null);
                                }
                            }

                        }
                    }
                    else
                    {
                        PropertyInfo relatedProperty = objBusinessObject.GetType().GetProperty(prop.Name);
                        if (relatedProperty != null)
                        {
                            object objValue = relatedProperty.GetValue(objBusinessObject, null);
                            prop.SetValue(MainObject, objValue, null);
                        }
                    }
                }

            }

            UpdateMainObjectBindingSource();
        }

        protected virtual void GenerateModuleItemsFromRelatedModuleMainObjectsInfo(BusinessObject objRelatedModuleMainObjectInfo)
        {

        }

        public virtual ERPModuleItemsEntity GenerateERPModuleItemsEntityFromRelatedERPModuleItemsEntity(BusinessObject objRelatedModuleItemsInfo, double dbRemainQty)
        {
           
            String strMainTableName = THSUtil.GetTableNameFromBusinessObject(MainObject);
            String strRelatedModuleItemsTableName = THSUtil.GetTableNameFromBusinessObject(objRelatedModuleItemsInfo);
            String strMainTablePrimaryKey = THSDbUtil.GetTablePrimaryColumn(strMainTableName);
            String strModuleItemsTableName = strMainTableName.Substring(0, strMainTableName.Length - 1) + "Items";
            String strModuleItemProductQtyOldPropertyName = strModuleItemsTableName.Substring(0, strModuleItemsTableName.Length - 1) + "ProductQtyOld";
            String strModuleItemProductQtyPropertyName = strModuleItemsTableName.Substring(0, strModuleItemsTableName.Length - 1) + "ProductQty";
            String strRelatedModuleItemProductQtyPropertyName = strRelatedModuleItemsTableName.Substring(0, strRelatedModuleItemsTableName.Length - 1) + "ProductQty";

            ERPModuleItemsEntity entModuleItems = ERPModuleItemsEntityFactory.GetModuleItemsEntity(this.Module.Name);
            BusinessObject objModuleItemsInfo = BusinessObjectFactory.GetBusinessObject(strModuleItemsTableName + "Info");


            PropertyInfo[] properties = objModuleItemsInfo.GetType().GetProperties();
            foreach (PropertyInfo prop in properties)
            {
                if (!THSDbUtil.IsPrimaryKey(strModuleItemsTableName, prop.Name))
                {
                    if (!THSDbUtil.IsForeignKey(strModuleItemsTableName, prop.Name))
                    {
                        if (prop.Name.StartsWith(strModuleItemsTableName.Substring(0, strModuleItemsTableName.Length - 1)))
                        {
                            String strRelatedModuleItemPropertyName = strRelatedModuleItemsTableName.Substring(0, strRelatedModuleItemsTableName.Length - 1) + prop.Name.Substring(strModuleItemsTableName.Length - 1);
                            PropertyInfo relatedModuleItemProperty = objRelatedModuleItemsInfo.GetType().GetProperty(strRelatedModuleItemPropertyName);
                            if (relatedModuleItemProperty != null)
                            {
                                object objValue = relatedModuleItemProperty.GetValue(objRelatedModuleItemsInfo, null);
                                prop.SetValue(objModuleItemsInfo, objValue, null);
                            }
                        }
                    }
                    else
                    {
                        if (!prop.Name.Equals(strMainTablePrimaryKey))
                        {
                            PropertyInfo relatedModuleItemProperty = objRelatedModuleItemsInfo.GetType().GetProperty(prop.Name);
                            if (relatedModuleItemProperty != null)
                            {
                                object objValue = relatedModuleItemProperty.GetValue(objRelatedModuleItemsInfo, null);
                                prop.SetValue(objModuleItemsInfo, objValue, null);
                            }
                        }
                    }
                }
            }

            //Set Quantity Ship
            THSDbUtil.SetPropertyValue(
                    objModuleItemsInfo,
                    strModuleItemProductQtyOldPropertyName,
                    0);
            THSDbUtil.SetPropertyValue(
                    objModuleItemsInfo,
                    strModuleItemProductQtyPropertyName,
                    Convert.ToDouble(THSDbUtil.GetPropertyValue(objRelatedModuleItemsInfo, strRelatedModuleItemProductQtyPropertyName)) - dbRemainQty);

            entModuleItems.GetFromBusinessObject(objModuleItemsInfo);

         
            AddExtraListsToModuleItemsEntity(entModuleItems, objRelatedModuleItemsInfo);

            return entModuleItems;
        }

        protected virtual void AddExtraListsToModuleItemsEntity(ERPModuleItemsEntity entModuleItems, BusinessObject objRelatedModuleItemsInfo)
        {

        }

        protected virtual List<FATransactionsInfo> GenerateModuleItemTransactionsFromRelatedModuleItemsInfo(BusinessObject objRelatedModuleItemsInfo)
        {
            FATransactionsController objFATransactionsController = new FATransactionsController();
            List<FATransactionsInfo> lstModuleItemFATransactions = new List<FATransactionsInfo>();
            
            return lstModuleItemFATransactions;
        }        
#endif
        #endregion
    }
}
